<template>
  <!--中间面板-->
  <div class="center-board">
    <div class="action-bar">
      <el-button icon="el-icon-view" type="text" @click="preview">预览</el-button>
      <el-button icon="el-icon-tickets" type="text" @click="save">保存</el-button>
      <el-button class="delete-btn" icon="el-icon-delete-solid" type="text" @click="clear">清空</el-button>
    </div>
    <el-scrollbar class="center-scrollbar">
      <el-row class="center-board-row" :gutter="formConf.gutter">
        <el-form
          :size="formConf.size"
          :label-position="formConf.labelPosition"
          :disabled="formConf.disabled"
          :label-width="formConf.labelWidth + 'px'"
        >
          <draggable
            class="drawing-board"
            :list="list"
            :animation="100"
            group="componentsGroup"
            draggable=".drawing-item"
          >
            <design-item
              v-for="(element, index) in list"
              :key="index"
              :model="element"
              :activeItem="activeItem"
              @rowItemRollBack="handlerRollBack"
              @onActiveItemChange="handlerActiveItemChange"
              @copyItem="handlerItemCopy"
              @deleteItem="handlerItemDelete"
            />
          </draggable>
          <div v-show="infoShow" class="empty-info">
            <el-empty description="从左侧拖拽添加控件"></el-empty>
          </div>
        </el-form>
      </el-row>
    </el-scrollbar>
    <config-panel :activeItem="activeItem" :itemList="list" />
    <!-- 设计器配置弹出框 -->
    <el-dialog :visible.sync="formConfVisible" width="50%" top="30px" :center="true">
      <el-tabs v-model="activeName">
        <el-tab-pane label="表单配置" name="formConf">
          <el-form ref="formConf" :model="formConf" label-width="100px">
            <el-form-item label="表单名">
              <el-input class="input" v-model="formConf.formRef"></el-input>
            </el-form-item>
            <el-form-item label="表单模型">
              <el-input class="input" v-model="formConf.formModel"></el-input>
            </el-form-item>
            <el-form-item label="校验模型">
              <el-input class="input" v-model="formConf.formRules"></el-input>
            </el-form-item>
            <el-form-item label="表单尺寸">
              <el-radio-group v-model="formConf.size">
                <el-radio-button label="medium">中等</el-radio-button>
                <el-radio-button label="small">较小</el-radio-button>
                <el-radio-button label="mini">迷你</el-radio-button>
              </el-radio-group>
            </el-form-item>
            <el-form-item label="标签对齐">
              <el-radio-group v-model="formConf.labelPosition">
                <el-radio-button label="right">右对齐</el-radio-button>
                <el-radio-button label="left">左对齐</el-radio-button>
                <el-radio-button label="top">顶部对齐</el-radio-button>
              </el-radio-group>
            </el-form-item>
            <el-form-item label="标签宽度">
              <el-input-number v-model="formConf.labelWidth" :min="60" :max="140"></el-input-number>
            </el-form-item>
            <el-form-item label="栅格间隔">
              <el-input-number v-model="formConf.gutter" :min="0" :max="30"></el-input-number>
            </el-form-item>
            <el-form-item label="动态表格支持组件高亮显示">
              <el-switch v-model="formConfig.dynamicTableAllowed"></el-switch>
            </el-form-item>
            <el-form-item label="禁用表单">
              <el-switch v-model="formConf.disabled"></el-switch>
            </el-form-item>
          </el-form>
        </el-tab-pane>
        <!-- <el-tab-pane label="提交前" name="fourth">开发中...</el-tab-pane> -->
      </el-tabs>
      <span slot="footer" class="dialog-footer">
        <el-button type="primary" @click="handlerSaveFormConf">确 定</el-button>
      </span>
    </el-dialog>
    <el-dialog :visible.sync="previewVisible" width="70%" title="预览">
      <preview
          class="shoview"
        v-on:showview="showview"
        :itemList="itemList"
        :formConf="formConf"
        v-if="previewVisible"
      />
    </el-dialog>
    <el-dialog
      :visible.sync="JSONVisible"
      width="70%"
      title="JSON"
      center
      :close-on-click-modal="false"
    >
      <codemirror v-model="viewCode" :options="options" />
      <span slot="footer" class="dialog-footer">
        <el-button type="primary" @click="handlerSetJson()">确 定</el-button>
      </span>
    </el-dialog>
    <el-dialog
      :title="formtitle"
      :visible.sync="dialogVisible"
      width="600px"
      :before-close="handleClose"
    >
      <el-form ref="form" :model="form" label-width="120px" :rules="rules">
        <el-form-item label="表单名称" prop="tableName">
          <el-input v-model="form.tableName" placeholder="请输入表单名称"></el-input>
        </el-form-item>
        <!-- <el-form-item label="分组名称" prop="groupName">
          <el-input v-model="form.groupName" placeholder="请输入分组名称"></el-input>
        </el-form-item> -->
        <el-form-item label="表单排序" prop="seqNo">
          <el-input-number v-model="form.seqNo" :min="1" placeholder="请输入表单排序"></el-input-number>
        </el-form-item>
        <el-form-item label="是否可以删除" prop="canDelete">
          <el-radio-group v-model="form.canDelete" :disabled="formtitle==='编辑表单'">
            <el-radio :label="1">是</el-radio>
            <el-radio :label="0">否</el-radio>
          </el-radio-group>
        </el-form-item>
      </el-form>
      <span slot="footer" class="dialog-footer">
        <el-button @click="dialogVisible = false">取 消</el-button>
        <el-button type="primary" @click="submit">确 定</el-button>
      </span>
    </el-dialog>
  </div>
</template>
<script>
import draggable from "vuedraggable";
import { api } from "../server/api";
import configPanel from "./configPanel";
import designItem from "./designItem";
import { getSimpleId } from "./utils/IdGenerate";
import { isLayout } from "./utils/index";
import formConf from "./custom/formConf";
import preview from "./preview";
import { codemirror } from "vue-codemirror";
// 核心样式
import "codemirror/lib/codemirror.css";
// 引入主题后还需要在 options 中指定主题才会生效
import "codemirror/theme/dracula.css";
import "codemirror/mode/javascript/javascript";

export default {
  name: "Designer",
  components: {
    draggable,
    configPanel,
    designItem,
    preview,
    codemirror
  },
  props: {
    list: {
      type: Array,
      default: []
    },
    formConfig: {
      type: Object,
      default: formConf
    },
    moduleId: {
      type: Number
    }
  },
  data() {
    return {
      formConf: formConf,
      activeItem: {},
      lastActiveItem: {},
      formConfVisible: false,
      previewVisible: false,
      JSONVisible: false,
      itemList: [],
      activeName: "formConf",
      editorCode: "",
      viewCode: "",
      dialogVisible: false,
      formtitle: "",
      form: { tableName: "", seqNo: 1, canDelete: 1,groupName:'' },
      rules: {
        tableName: [
          { required: true, message: "请输入表单名称", trigger: "blur" }
        ],
        seqNo: [{ required: true, message: "请输入表单排序", trigger: "blur" }],
        canDelete: []
      },
      // 默认配置
      options: {
        tabSize: 2, // 缩进格式
        theme: "dracula", // 主题，对应主题库 JS 需要提前引入
        lineNumbers: true, // 显示行号
        line: true,
        styleActiveLine: true, // 高亮选中行
        hintOptions: {
          completeSingle: true // 当匹配只有一项的时候是否自动补全
        }
      }
    };
  },
  mounted() {},
  methods: {
    showview() {
      this.previewVisible = false;
    },
    preview() {
      const clone = JSON.parse(JSON.stringify(this.list));
      this.itemList = clone;
      this.previewVisible = true;
    },
    viewJSON() {
      this.viewCode = this.code;
      this.JSONVisible = true;
    },
    view() {
      localStorage.setItem("formValue", this.code);
      window.open("#/view");
    },
    setting() {
      this.formConfVisible = true;
    },
    clear() {
      this.$confirm("此操作将清空整个表单,是否继续?").then(() => {
        this.$emit("clear");
      });
    },
    handlerActiveItemChange(obj) {
      this.lastActiveItem = this.activeItem;
      this.activeItem = obj;
    },
    handleClose(done) {
      this.$refs.form.resetFields();
      done();
    },
    handlerItemCopy(origin, parent) {
      if (isLayout(origin)) {
        //布局组件，需要复制布局组件以及下面的组件
        const clone = JSON.parse(JSON.stringify(origin));
        const uId = "row_" + getSimpleId();
        clone.id = uId;
        clone._id = uId;
        clone.columns.map(column => {
          let itemList = [];
          column.list.map((item, i) => {
            const cloneitem = JSON.parse(JSON.stringify(item));
            const uId = "fd_" + getSimpleId();
            cloneitem.id = uId;
            cloneitem._id = uId;
            itemList.push(cloneitem);
          });
          column.list = [];
          column.list = itemList;
        });
        this.list.push(clone);
        this.handlerActiveItemChange(clone);
      } else {
        //如果是普通组件，需要判断他是否再布局组件下。
        if (parent) {
          parent.columns.map(column => {
            if (column.list.some(item => item.id === origin.id)) {
              const clone = JSON.parse(JSON.stringify(origin));
              const uId = "fd_" + getSimpleId();
              clone.id = uId;
              clone._id = uId;
              column.list.push(clone);
              this.handlerActiveItemChange(clone);
            }
          });
        } else {
          const clone = JSON.parse(JSON.stringify(origin));
          const uId = "fd_" + getSimpleId();
          clone.id = uId;
          clone._id = uId;
          this.list.push(clone);
          this.handlerActiveItemChange(clone);
        }
      }
    },
    handlerItemDelete(origin, parent) {
      if (isLayout(origin)) {
        //如果是布局组件,则直接删除
        const index = this.list.findIndex(item => item.id === origin.id);
        this.list.splice(index, 1);
      } else {
        //如果不是布局组件，则先判断是不是再布局内部，如果不是，则直接删除就可以，如果是，则要在布局内部删除
        if (parent) {
          parent.columns.map((column, index) => {
            const colIndex = column.list.findIndex(
              item => item.id === origin.id
            );
            if (colIndex > -1) {
              column.list.splice(colIndex, 1);
            }
          });
        } else {
          const index = this.list.findIndex(item => item.id === origin.id);
          this.list.splice(index, 1);
        }
      }
    },
    handlerSaveFormConf() {
      this.formConfVisible = false;
    },
    handlerRollBack(rowItem, oldIndex) {
      //还原
      this.list.splice(oldIndex, 0, rowItem);
    },
    handlerSetJson() {
      this.$emit("updateJSON", this.viewCode);
      this.JSONVisible = false;
    },
    reportruls(arrtwo) {
      let arr=JSON.parse(JSON.stringify(arrtwo)).filter(val=>{
        return val
      })
      let fidlist = [];
       console.log(222)
      const clone = JSON.parse(JSON.stringify(arr));
        console.log(clone)
      const sqNo = 0;      
      const finvalue = arr.filter(value => {
       
        return value.fieldType === "IdentityKey";
      });
      if (finvalue.length < 1) {
        let option = {
          fieldType: "IdentityKey",
          label: "id",
          required: true
        };
        arr.push(option);
      }
      arr.map((val, index) => {
       
        let span = val.span;
        delete val.privateInfo;
        delete val.user;
        let obj = {
          fieldType: val.fieldType,
          fieldName: val.label ? val.label : val.text,
          isMandatory: val.required ? val.required : false,
          seqNo: index + 1
        };
        if (val.fieldType === "InputText") {
          obj.privateInfo = JSON.stringify({
            dataLen: val.dataLen,
            isUniquey: val.isUniquey,
            user: JSON.stringify(val),
            format: val.rulesType === "default" ? null : val.rulesType
          });
        }
        //if (val.fieldType === "IdentityKey") {
        //obj.isMandatory = true;
        //obj.privateInfo = JSON.stringify({
        //user: JSON.stringify(val)
        //});
        //}
        if (val.fieldType === "InputDate") {
          obj.privateInfo = JSON.stringify({
            format: val.format,
            user: JSON.stringify(val)
          });
        }
        if (val.fieldType === "Tab") {
          console.log(val)
           obj.fieldName=val.text
             obj.privateInfo = JSON.stringify({
            fieldNames: val.fieldNames,
          });
        }
        if (val.fieldType === "File"||val.fieldType === "Image") {
          console.log(val)
          obj.privateInfo = JSON.stringify({
            fileNum: val.fileNum,
            user: JSON.stringify(val)
          });
        }
        if (val.fieldType === "InputNumber") {
          obj.privateInfo = JSON.stringify({
            precision: val.precision,
            format: val.rulesType,
            minimum: val.min * Math.pow(10, val.precision),
            maximum: val.max * Math.pow(10, val.precision),
            user: JSON.stringify(val)
          });
        }
        if (val.fieldType === "Textarea") {
          obj.privateInfo = JSON.stringify({
            user: JSON.stringify(val)
          });
        }
         if (val.fieldType === "ChildForm") {
           console.log(val)
          obj.privateInfo = JSON.stringify({
            childTid: val.tableid,
              user: JSON.stringify(val),
          });
        }
        if (val.fieldType === "HorizontalLine") {
           val.span=24
          obj.privateInfo = JSON.stringify({
            user: JSON.stringify(val),
            showTitle: val.showTitle
          });
        }
        if (val.fieldType === "RichText") {
          obj.privateInfo = JSON.stringify({
            user: JSON.stringify(val)
          });
        }
         if (val.fieldType === "CombineValue") {
           obj.fieldName=val.text
           obj.privateInfo = JSON.stringify({
            user: JSON.stringify(val),
            fieldNames:val.fieldNames,
            function:val.function,
            valType:val.valType
          });
        }
        if (val.fieldType === "Reference") {
           obj.fieldName=val.text
           obj.privateInfo = JSON.stringify({
            user: JSON.stringify(val),
            refFldId:val.refFldId,

          });
        }
        if (
          val.fieldType === "SelectRadio" ||
          val.fieldType === "SelectCheck" ||
          val.fieldType === "RadioBox" ||
          val.fieldType === "Checkbox"
        ) {
          const { options } = val;
          const valLst = [];
          options.forEach(element => {
            val.dataType === "dynamic"
              ? valLst.push(element.value)
              : valLst.push(element.label);
          });
          obj.isMandatory = false;
          obj.privateInfo = JSON.stringify({
            user: JSON.stringify(val),
            dictTblId: val.dataType === "dynamic" ? valLst.join(",") : null,
            valLst: val.dataType === "static" ? valLst : null,
            hasOther: false
          });
          console.log(val.fieldType, valLst, obj.privateInfo, "选择");
        }
        if (this.$route.query.name) {
          obj.fieldId = val.fieldId;
        }
        fidlist.push(obj);
      });
      return fidlist;
    },
    isRepeat(arr) {
        console.log(111);
      const fieldName = arr.map(value => value.fieldName);
      console.log(fieldName);
      const fieldNameSet = new Set(fieldName);
      console.log(fieldNameSet);
      return fieldNameSet.size == fieldName.length;
    },
    save() {
      const clone = JSON.parse(JSON.stringify(this.list));
      console.log(1)
      if (!this.isRepeat(this.reportruls(clone))) {
        this.$message.warning("表单组件名称存在重复");
        return;
      }
       console.log(2)
      this.dialogVisible = true;
      this.formtitle = this.$route.query.name ? "编辑表单" : "添加表单";
        console.log(3)
      this.$set(
        this.form,
        "canDelete",
        this.$route.query.canDelete ? this.$route.query.canDelete : 1
      );
       console.log(4)
      this.$set(this.form, "tableName", this.$route.query.name);
      this.$set(this.form, "groupName", this.$route.query.groupName);
    },
    fromdesiger(par){
      if (this.$route.query.name) {
        let pars = { ...par, tableId: this.$route.query.tableId };
        console.log(pars)
        api.stdappTableUpdTable(pars).then(res => {
          this.$message({
            type: "success",
            message: "修改成功!"
          });
          this.dialogVisible = false;
        });
      } else {
        let pars = { ...par, moduleId: this.$route.query.moduleId };
          console.log(pars)
        api.stdappTableAddTable(pars).then(res => {
          this.$message({
            type: "success",
            message: "添加成功!"
          });
          this.dialogVisible = false;
        });
      }
    },
    fromliucheng(par){
      if (this.$route.query.name) {
        let pars = { ...par, tableId: this.$route.query.tableId };
          console.log(pars)
        api.stdappTableUpdFlow(pars).then(res => {
          this.$message({
            type: "success",
            message: "修改成功!"
          });
          this.dialogVisible = false;
        });
      } else {
        let pars = { ...par, moduleId: this.$route.query.moduleId };
          console.log(pars)
        api.stdappTableAddFlow(pars).then(res => {
          this.$message({
            type: "success",
            message: "添加成功!"
          });
          this.dialogVisible = false;
        });
      }
    },
    submit() {
      console.log(this.reportruls(JSON.parse(JSON.stringify(this.list))))
      this.$refs["form"].validate(valid => {
        if (valid) {
          let par = {
            ...this.form,
            isChild: this.$route.query.isChild,
            fieldLst: this.reportruls(JSON.parse(JSON.stringify(this.list)))
          };
        
          if(parseInt(this.$route.query.tableType)===3){
             this.fromliucheng(par)
          }else{
            this.fromdesiger(par)
          }
        }
      });
    }
  },
  computed: {
    infoShow() {
      return this.list.length < 1;
    },
    code() {
      let json = {};
      json.config = this.formConf;
      json.list = this.list;
      return JSON.stringify(json, null, 4);
    }
  },
  watch: {
    activeItem(newValue, oldValue) {
      this.lastActiveItem = oldValue;
    }
  }
};
</script>
<style  scoped>
.el-rate {
  display: inline-block;
}
.center-scrollbar >>> .el-scrollbar__bar.is-horizontal {
  display: none;
}
.center-scrollbar >>> .el-scrollbar__wrap {
  overflow-x: hidden;
}
.empty-info >>> .el-empty__description p {
  color: #ccb1ea;
  font-size: 16px;
}
</style>
<style lang="scss">
@import "./style/designer.scss";
</style>
<style>
@import "./style/designer.css";
</style>
